<template>
  <div class="inspect-center-page">
    <div class="center-entry">
      <img src="/images/inspect-log.png" />
      <ul class="center-entry-list">
        <li v-for="item in inspectObjects" :class="{'inspecting': item.id === inspectingId, 'inspect-error': item.id === inspectingId && inspectResult[2] > 0}">
          <div class="center-img">
            <img :src="item.img" v-if="item.id !== inspectingId" />
            <img :src="item.imgOk" v-else-if="item.id === inspectingId && inspectResult[2] === 0" />
            <img :src="item.imgWrong" v-else-if="item.id === inspectingId && inspectResult[2] > 0" />
          </div>
          <Dropdown class="dropdown-inspect-select" trigger="custom" :visible="visible">
            <a class="center-inspect-button" @click="visible = true">环境巡检 <Icon type="ios-arrow-down"></Icon> </a>
            <div slot="list" class="dropdown-menus">
              <div class="dropdown-search-inspect flex">
                <div class="search-inspect flex-1">
                  <Icon type="ios-search" />
                  <Input v-model="searchInspect" size="small" @on-change="search" ></Input>
                </div>
                <div class="inspect-btn" @click="websocketInspect(item)">
                  <Tooltip content="开始巡检" placement="top">
                    <Icon type="md-arrow-forward" />
                  </Tooltip>
                </div>
              </div>
              <div class="dropdown-list">
                <div class="flex" :class="{'active': selectEnv === env.environmentId}" v-for="env in environments" :key="env.environmentId"
                  @click="selectEnvironment(env)">
                  <div class="flex-1 f-nowrap">{{env.environmentName ? env.environmentName : env.environmentId}}</div>
                  <div class="flex-check">
                    <Icon type="ios-checkmark" />
                  </div>
                </div>
              </div>
            </div>
          </Dropdown>
          <i class="center-triangle"></i>
        </li>
      </ul>
    </div>
    <zl-progress v-model="progressExtra" :switch="inspectSwtich" :heart="50" :time="8" :threshold="70" :isError="inspectResult[2] > 0"></zl-progress>
    <div class="center-preview flex">
      <div class="flex-status">
        <div class="status-bar" :class="{'inspecting': isInspectFlag === 'begin', 'inspect-error': inspectResult[2] > 0}">
          <i></i>
          <span>{{inspectStatus}}</span>
        </div>
      </div>
      <div class="flex-1">
        <h4 v-if="!isInspectFlag">上次巡检时间： {{previous.inspectTime}}</h4>
        <h4 v-if="isInspectFlag === 'begin' && !inspectNow">开启巡检<span class="animate-dot">...</span></h4>
        <h4 v-if="isInspectFlag === 'begin' && inspectNow">正在进行{{inspectNow}}<span :class="{'animate-dot': isInspectFlag === 'begin'}">...</span></h4>
        <h4 v-if="isInspectFlag === 'end'">本次巡检结束！</h4>
        <p v-if="!isInspectFlag">
          <span>巡检类型： {{previous.inspectTypeName}}</span>
          <span>巡检结果：
            <span :class="{'color-green': previous.inspectResult === '正常', 'color-red': previous.inspectResult === '异常'}">{{previous.inspectResult}}</span>
          </span>
        </p>
      </div>
      <div class="flex-mani" v-if="isInspectFlag === 'begin'">
        <img src="/images/close.png" @click="closeInspect" />
      </div>
    </div>
    <Row class="center-info" v-if="!isInspectFlag">
      <Col :span="12">
        <h4 class="center-info-title"><img src="/images/normal.png" /><span>巡检综合评分</span></h4>
        <p class="color-blue center-info-number">{{previous.recordValue}}</p>
      </Col>
      <Col :span="12">
        <h4 class="center-info-title"><img src="/images/abnormal.png" /><span>巡检异常数</span></h4>
        <p class="color-blue center-info-number">{{previous.errorNum}}</p>
      </Col>
    </Row>

    <Card class="inspect-table" v-if="isInspectFlag">
      <div class="inspect-table-options">
        <a v-for="(option, optionIndex) in options" :class="{'active': optionIndex === selectOption}" :key="optionIndex" @click="switchOption(optionIndex)">{{option}}</a>
      </div>
      <Table :columns="columns" :data="inspectData"></Table>
    </Card>

  </div>
</template>
<script type="text/javascript">
import InspectItem from '@/components/inspect-item'
import ZlProgress from '@/components/progress'
import Fetch from '@/api/request'

export default {
  components: {
    ZlProgress
  },
  data() {
    return {
      inspectingId: '',
      inspectItemObj: {},
      inspectObjects: [],
      options: ['总量（0）', '正常（0）', '异常（0）'],
      selectOption: 0,
      previous: {},
      inspectData: [],
      inspectDataMeta: [],
      columns: [{
        type: 'expand',
        width: 50,
        align: 'center',
        render: (h, params) => {
          return h(InspectItem, {
            props: {
              inspectItemInfoList: params.row.inspectItemInfoList ? params.row.inspectItemInfoList : []
            }
          })
        }
      }, {
        title: '巡检类型',
        key: 'inspectTypeName'
      }, {
        title: '巡检对象',
        key: 'inspectObjectName'
      }, {
        title: '巡检结果',
        key: 'inspectObjectResult',
        render: (h, params) => {
          if (params.row.inspectObjectResult === '正常') {
            return h('span', {
              style: {
                color: '#65beb2'
              }
            }, '正常')
          } else if (params.row.inspectObjectResult === '异常') {
            return h('span', {
              style: {
                color: '#e45049'
              }
            }, '异常')
          }
        }
      }],
      inspectStatus: '休',
      ws: null,
      inspectStartFlag: '',
      isInspectFlag: '',  // 空：未进行  begin: 开始  end: 结束
      inspectNow: '',
      inspectResult: [0, 0, 0], // 巡检结果： [总量，正常数，异常数]
      inspectSwtich: '',
      progressExtra: 0,
      wsURL: '',
      environments: [],
      metaEnvs: [],
      searchInspect: '',
      selectEnv: '',
      visible: false
    }
  },
  mounted() {
    let vm = this
    vm.getInspectType()
    vm.previousResult()
    vm.getEnvs()
    vm.$nextTick(function () {
      document.body.addEventListener('click', function (event) {
        let node = event.target
        let hasDropdown = false
        while (node) {
          if (node.className && node.className.includes('dropdown-inspect-select')) {
            hasDropdown = true
          }
          node = node.parentNode
        }
        if (!hasDropdown) {
          vm.visible = false
        }
      })
    })
  },
  methods: {
    // 选择环境
    selectEnvironment(env) {
      this.selectEnv = env.environmentId
      for (let i = 0; i < this.inspectObjects.length; i++) {
        const inspect = this.inspectObjects[i]
        if (inspect.name === '环境巡检') {
          inspect.env = this.selectEnv
        }
      }
    },
    // 搜索
    search() {
      this.environments = this.metaEnvs.filter((env) => {
        if (env.environmentName) {
          if (env.environmentName.indexOf(this.searchInspect) !== -1) {
            return true
          }
        } else {
          if (env.environmentId.indexOf(this.searchInspect) !== -1) {
            return true
          }
        }
      })
    },
    // 获取所有的环境列表
    getEnvs() {
      Fetch.get({
        url: '/api/environment'
      }).then((res) => {
        if (res && res.code === '0') {
          this.metaEnvs = res.data
          this.environments = res.data
        } else {
          this.$Message.warning({
            content: res.message,
            duration: this.DURATION
          })
        }
      }).catch((err) => {
        this.$Message.error(err.message)
      })
    },
    // 获取巡检类型
    getInspectType() {
      Fetch.get({
        url: '/api/inspect/config/findParentType'
      }).then((res) => {
        if (res.data && Array.isArray(res.data)) {
          for (let i = 0; i < res.data.length; i++) {
            const inspect = res.data[i]
            if (inspect.inspectTypeName === '环境巡检') {
              localStorage.setItem('inspectTypeId', inspect.inspectTypeId)
              this.inspectObjects.push({
                id: inspect.inspectTypeId,
                name: inspect.inspectTypeName,
                env: '',
                img: '/images/inspect-enviroment.png',
                imgOk: '/images/inspect-enviroment-ok.png',
                imgWrong: '/images/inspect-enviroment-wrong.png'
              })
            }
          }
        }
      })
    },
    // 结束巡检
    closeInspect() {
      this.ws && this.ws.close()
      this.isInspectFlag = 'end'
      this.inspectStatus = '完成'
    },
    // 获取最近一次巡检结果
    previousResult() {
      Fetch.get({
        url: '/api/inspect/lastRecord'
      }).then((data) => {
        this.previous = data.data || {}
        if (data.url) {
          this.wsURL = data.url.replace(/http(s?):\/\//gi, '')
        }
      })
    },
    // 开启websocket进行巡检
    websocketInspect(item) {
      let vm = this
      // 查看是否选择了环境
      if (!item.env) {
        this.$Message.warning({
          content: '请先选择一个环境!',
          duration: this.DURATION
        })
        return
      }
      // 阻止多次生成websocket
      if (vm.ws) {
        return
      }
      this.visible = false
      this.inspectItemObj = item
      this.inspectingId = item.id
      this.inspectStartFlag = item.id + ',' + item.name + ',' + item.env
      this.inspectData = []
      this.inspectDataMeta = []
      this.inspectNow = ''
      this.inspectSwtich = 'start'
      vm.ws = new WebSocket('ws://' + this.wsURL + '/websocket/inspect')
      vm.ws.onopen = vm.wsOnopen
      vm.ws.onmessage = vm.wsOnmessage
      vm.ws.onclose = vm.wsOnclose
    },
    wsOnopen() {
      this.isInspectFlag = 'begin'
      this.inspectStatus = '巡检'
      this.inspectSwtich = 'start'
      this.inspectResult = [0, 0, 0]
      this.ws.send(this.inspectStartFlag)
    },
    // 巡检接收消息
    wsOnmessage(evt) {
      let jsonData = JSON.parse(evt.data)
      console.log(jsonData)
      if (jsonData) {
        // 用于查看websocket返回数据
        if (jsonData.flag === 1 && jsonData.inspectTypeName) { // inspectTypeName用于防止接受null
          if (jsonData.inspectObjectResult === '正常') {
            jsonData._disableExpand = true
          }
          // 过滤重复数据
          let isReplace = false
          for (let i = 0; i < this.inspectDataMeta.length; i++) {
            let inspect = this.inspectDataMeta[i]
            // 名称相同， 且存在异常值才替换
            if (jsonData.inspectObjectName === inspect.inspectObjectName) {
              isReplace = true
              if (jsonData.inspectItemInfoList && jsonData.inspectItemInfoList.length > 0) {
                this.inspectDataMeta.splice(i, 1, jsonData)
                this.inspectData.splice(i, 1, jsonData)
              }
              break
            }
          }
          // 没有巡检过且巡检数据结果有值才存储数据
          if (!isReplace && jsonData.inspectObjectResult) {
            this.inspectData.push(jsonData)
            this.inspectDataMeta.push(jsonData)
            this.inspectNow = jsonData.inspectTypeName
            if (jsonData.inspectObjectResult === '异常') {
              ++this.inspectResult[2]
            } else if (jsonData.inspectObjectResult === '正常') {
              ++this.inspectResult[1]
            }
            ++this.inspectResult[0]
            this.options[0] = '总量（' + this.inspectResult[0] + '）'
            this.options[1] = '正常（' + this.inspectResult[1] + '）'
            this.options[2] = '异常（' + this.inspectResult[2] + '）'
          }
        } else if (jsonData.flag === -1) {
          this.closeInspect()
        }
        // 巡检页从底部显示，便于查看巡检结果
        this.$nextTick(function () {
          document.getElementById('layoutContent').scrollTop = document.getElementById('layoutContent').scrollHeight - document.getElementById('layoutContent').clientHeight
        })
      }
    },
    wsOnclose() {
      this.ws = null
      if (this.isInspectFlag === '') { // websocket未连接上
        this.$Message.info({
          content: 'websocket连接失败！',
          duration: 2
        })
        this.isInspectFlag = ''
        this.inspectStatus = '休'
        this.inspectingId = ''
        this.inspectSwtich = 'end'
      } else if (this.isInspectFlag === 'end' || this.isInspectFlag === 'begin') {
        this.isInspectFlag = 'end'
        this.inspectStatus = '完成'
        this.inspectSwtich = 'end'
      }
    },
    // 切换日志查询条件
    switchOption(index) {
      this.selectOption = index
      if (index === 0) { // 总量
        this.inspectData = this.inspectDataMeta
      } else if (index === 1) { // 正常
        this.inspectData = this.inspectDataMeta.filter((log) => {
          return log.inspectObjectResult === '正常'
        })
      } else if (index === 2) { // 异常
        this.inspectData = this.inspectDataMeta.filter((log) => {
          return log.inspectObjectResult === '异常'
        })
      }
    }
  },
  beforeDestroy() {
    // 避免退出页面websocket继续发送接收消息
    if (this.ws) {
      this.ws && this.ws.close()
    }
  }
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.center-entry {
  position: relative;
  width: 100%;
  height: 260px;
  text-align: center;
  > img {
    margin: auto;
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
  }
}
  .center-entry-list {
    position: relative;
    height: 100%;
    z-index: 2;
    padding-top: 50px;
    text-align: center;
    > li {
      display: inline-block;
      width: 140px;
      &.inspecting {
        .center-img {
          border-color: #4090f7;
        }
        .center-triangle {
          border-bottom-color: #4090f7;
        }
        .center-inspect-button {
          background-color: #4090f7;
          color: #fff;
        }
        &.inspect-error {
          .center-img {
            border-color: #e45049;
          }
          .center-triangle {
            border-bottom-color: #e45049;
          }
          .center-inspect-button {
            background-color: #e45049;
            color: #fff;
          }
        }
      }
    }
    .center-img {
      display: inline-block;
      padding: 10px;
      border: 1px solid transparent;
      border-radius: 50%;
      margin-bottom: 15px;
      img {
        width: 80px;
        height: 80px;
        border-radius: 50%;
      }
    }
    .center-inspect-button {
      display: inline-block;
      width: 104px;
      height: 36px;
      line-height: 36px;
      text-align: center;
      background-color: #fff;
      color: #2d8cf0;
    }
    .center-triangle {
      position: absolute;
      bottom: 2px;
      left: 50%;
      margin-left: -8px;
      border-left: 10px solid transparent;
      border-right: 10px solid transparent;
      border-bottom: 16px solid transparent;
    }
  }
  .center-bar {
    height: 10px;
    background-color: #ced7e0;
  }
  .center-preview {
    padding: 15px;
    background-color: #fff;
    margin-bottom: 10px;
    .flex-status {
      padding-right: 10px;
      .status-bar {
        position: relative;
        display: block;
        width: 64px;
        height: 64px;
        border-radius: 50%;
        text-align: center;
        line-height: 64px;
        font-size: 24px;
        color: #a3bad4;
        i {
          position: absolute;
          left: 0;
          right: 0;
          display: block;
          width: 64px;
          height: 64px;
          border-radius: 50%;
          border: 1px dashed #a3bad4;
        }
        &.inspecting {
          color: #4090f7;
          i {
            border-color: #4090f7;
            animation: 6s linear infinite rotating;
          }
        }
        &.inspect-error {
          color: #e45049;
          i {
            border-color: #e45049;
          }
        }
      }
    }
    .flex-1 {
      h4 {
        font-weight: normal;
        font-size: 24px;
        margin-bottom: 6px;
      }
      p {
        color: #999;
        font-size: 14px;
        span {
          margin-right: 10px;
        }
      }
    }
    .flex-mani {
      img {
        margin-right: 15px;
        cursor: pointer;
      }
    }
  }
  .center-info {
    background-color: #fff;
    margin-bottom: 60px;
    border-bottom: 1px solid #eee;
    border-right: 1px solid #eee;
    .center-info-title {
      font-weight: normal;
      img {
        width: 32px;
        vertical-align: middle;
      }
      span {
        vertical-align: middle;
        margin-left: 8px;
      }
    }
    .center-info-number {
      font-size: 32px;
      padding: 15px 0 10px 0;
    }
  }
  .center-info /deep/ {
    .ivu-col {
      padding: 15px 0 30px 15px;
      border-left: 1px solid #eee;
      border-top: 1px solid #eee;
    }
  }
.inspect-table {
  margin-top: 20px;
  .inspect-table-options {
    padding-bottom: 15px;
    a {
      display: inline-block;
      position: relative;
      line-height: 14px;
      padding: 0 10px;
      border-left: 1px solid #999;
      &:first-child {
        margin-left: -10px;
        border-left: 1px solid transparent;
      }
      &.active {
        color: #2d8cf0;
      }
    }
  }
}
.dropdown-search-inspect /deep/ {
  .search-inspect {
    .ivu-icon {
      position: absolute;
      z-index: 9;
      color: #999;
      top: 4px;
      left: 4px;
      font-size: 16px;
    }
    .ivu-input {
      padding-left: 24px;
    }
  }
  .inspect-btn {
    .ivu-icon {
      padding: 4px;
    }
  }
}
.dropdown-search-inspect {
  padding: 0 10px;
  .inspect-btn {
    margin-left: 6px;
    height: 24px;
    width: 24px;
    border: 1px solid #ccc;
    border-radius: 4px;
    color: #ccc;
    cursor: pointer;
  }
}
.search-inspect {
  position: relative;
  width: 130px;
}
.dropdown-list {
  max-height: 200px;
  overflow: auto;
}
.dropdown-list {
  padding: 6px 0;
  .flex-check {
    .ivu-icon {
      display: none;
      font-size: 24px;
    }
  }
  .flex {
    padding: 0 3px 0 10px;
    line-height: 26px;
    cursor: pointer;
    &:hover {
      background-color: #eee;
    }
    &.active {
      color: #2d8cf0;
      background-color: #d8dfe7;
      .ivu-icon {
        display: inline-block;
      }
    }
  }
}
</style>
